//
//  DetailTableEdit.m
//  SplitForce
//
//  Created by Ron Hess on 7/20/10.
//  Copyright 2010 Salesforce.com. All rights reserved.
//

#import "DetailTableEdit.h"

@implementation DetailTableEdit

 
// really we are only drawing the detail of the page layout at this time, not the edit, not the related lists
@synthesize theLayout, detailLayouSections,detailItem,describe;

UIView *scrollView  = nil;			// will need to resize the scroll area for sliding in keyboard
UITextField *activeText = nil;		// track the focus
Boolean keyboardShown = NO;
NSInteger  adjustment = 0;			// how much did we shrink the scrollView

#pragma mark -
#pragma mark Initialization

- (id)initWithStyle:(UITableViewStyle)style 
{
    // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
    self = [super initWithStyle:style];
	
	SplitForceAppDelegate *app = (SplitForceAppDelegate *)[[UIApplication sharedApplication] delegate];

	// these hit the cache we setup in root view controller, no need for async
	describe = [[app.rootViewController.client describeSObject:@"Account"] retain];

	NSArray *layouts = [[app.rootViewController.client describeLayout:@"account"] layouts];
	
	theLayout = [layouts objectAtIndex:0];	// this is just the first layout, not a particular layout 
	
	detailLayouSections = [[theLayout detailLayoutSections] copyWithZone:nil]; 
	
	[self registerForKeyboardNotifications];
	return self;
}


- (void) endEditing 
{
	[activeText endEditing:YES];
	activeText = nil;
}


- (void)registerForKeyboardNotifications {
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(keyboardWasShown:)
												 name:UIKeyboardDidShowNotification object:nil];
	
    [[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(keyboardWasHidden:)
												 name:UIKeyboardDidHideNotification object:nil];
}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
	
    if (keyboardShown)
		return;
	
    NSDictionary* info = [aNotification userInfo];
    // Get the size of the keyboard.
	
    NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
	
    CGSize keyboardSize = [aValue CGRectValue].size;
	
	NSLog(@"keyboardSize h:%f w:%f",keyboardSize.height,keyboardSize.width);
	
    // Resize the scroll view (which is the root view of the window)
	
    CGRect viewFrame = [scrollView frame];
	NSLog(@" viewFrame %f",viewFrame.size.height);

	// the math matters, in landscape height > width, in portrait width > height
	if ( UIDeviceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ) {	
		NSLog(@" is portrait "); 
		adjustment = keyboardSize.height;
	} else { 
		NSLog(@" is landscape "); 
		adjustment = keyboardSize.width;
	}

	viewFrame.size.height -= adjustment;
	//NSLog(@" viewFrame %f",viewFrame.size.height);
	scrollView.frame = viewFrame;
	
	
    // Scroll the active text field into view, really the superview of the text field ( the table cell) is needed
    CGRect textFieldRect = [[activeText superview ] frame];
	
    [(UITableView *)scrollView  scrollRectToVisible:textFieldRect animated:YES];
	
    keyboardShown = YES;	
}


// Called when the UIKeyboardDidHideNotification is sent

- (void)keyboardWasHidden:(NSNotification*)aNotification
{
	if ( ! keyboardShown)
		return;
	
	// Reset the height of the scroll view to its original value
    CGRect viewFrame = [scrollView frame];
	
    viewFrame.size.height += adjustment;
	
    scrollView.frame = viewFrame;
    keyboardShown = NO;
}


#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad 
{ 
	[super viewDidLoad]; 
	
	scrollView = super.view;
	
	//CGRect viewFrame = [scrollView frame];
	//NSLog(@"Detail Table Edit viewDidLoad viewFrame %f",viewFrame.size.height);
	
	// for some reason setting the frame to a new CGRect will cause the scroll frame to be correct
	CGRect r = self.tableView.frame;
	self.tableView.frame = CGRectMake(0,0,r.size.height,r.size.width);
}

#pragma mark -
#pragma mark Text field delegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
// A delegate method called by the URL text field when the editing is started. 
{
	activeText = textField;
	return YES;
}

/*
 * update the sobject with the contents of the ( possibably changed ) text
 */
- (void)textFieldDidEndEditing:(UITextField *)textField 
{
	NSInteger tt  =textField.tag;					// tag has the field index, we need field name

	ZKDescribeField *editField  = [[describe fields] objectAtIndex:tt];
	NSLog(@" field changed %@ to %@",editField.name,textField.text);
	
	// update detail item
	[detailItem setFieldValue:textField.text field:editField.name];
}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{	
	return [detailLayouSections count] ;
}

// Return the number of rows in the section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
	return [[[detailLayouSections objectAtIndex:section] layoutRows] count];	
}

- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section 
{
	return [[detailLayouSections objectAtIndex:section] heading];
}

- (NSString *) fieldValueFormattedFromItem : (ZKDescribeLayoutItem *)item 
{
	ZKDescribeLayoutComponent *laycomp = [[item layoutComponents] objectAtIndex:0];
	
	NSString *fieldName = [laycomp value];
	ZKDescribeField *field = [describe fieldWithName:fieldName];
	
	// set a formatted value
	NSString *val = [detailItem fieldValueFormatted:fieldName :field]; 
	
	return val!=nil?val:@"" ;
}
 


-(NSInteger) fieldIndexTag: (NSString *)name 
// turn a field name into an integer tag, used to tag each text field
{
	NSArray *ar = [describe fields]; 
	NSInteger mx = [ar count];
	NSInteger ret;
	for (ret = 0; ret <= mx; ret++) {
		
		ZKDescribeField *f = [ar objectAtIndex:ret];
		if ( [f.name isEqualToString:name] ) {
			//NSLog(@"%@ %d",f.name,ret);
			break;
		}
	}
	return ret; 
}

- (void	) textOrEdit:	(UITableViewCellFixed *)cell : 
						(ZKDescribeLayoutItem *) item :
						(CGRect ) frame
{	
	ZKDescribeLayoutComponent *laycomp = [[item layoutComponents] objectAtIndex:0];
	NSString *fieldName = [laycomp value];
	ZKDescribeField *field = [describe fieldWithName:fieldName];
	NSString *type = [field type] ;
	
	// TODO make a single column wider, currently each is the same width 

	if ( [type isEqualToString:@"reference"] ) {
		cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",[self fieldValueFormattedFromItem:item] ];
	}
	else {
		
		UITextField *playerTextField = [[UITextField alloc] initWithFrame:frame	];
		playerTextField.adjustsFontSizeToFitWidth = YES;
		playerTextField.textColor = [UIColor blackColor];
		//	playerTextField.placeholder = @"Required";
		playerTextField.keyboardType = UIKeyboardTypeDefault;
		playerTextField.backgroundColor = [UIColor whiteColor];
		playerTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
		playerTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
		playerTextField.textAlignment = UITextAlignmentLeft;
		playerTextField.tag = [self fieldIndexTag:fieldName];
		playerTextField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
		playerTextField.borderStyle =   UITextBorderStyleLine;
		[playerTextField setEnabled: YES];
		playerTextField.text = [self fieldValueFormattedFromItem:item];
		playerTextField.delegate = self;
		[cell addSubview:playerTextField];
	}
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
//	NSLog(@"section %d row %d",indexPath.section,indexPath.row);
	
    NSString *CellIdentifier = [NSString stringWithFormat:@"Cell %d %d",indexPath.section,indexPath.row];
    
    UITableViewCell *cell;
	cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCellFixed alloc] initWithStyle:UITableViewCellStyleValue2 
											reuseIdentifier:CellIdentifier] autorelease];		
		cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
	
    // Configure the cell...
	cell.accessoryType = UITableViewCellAccessoryNone; 

	ZKDescribeLayoutRow *dlr = [[[detailLayouSections objectAtIndex:indexPath.section] layoutRows] objectAtIndex:indexPath.row];
	@try {
		ZKDescribeLayoutItem *item = [[dlr layoutItems] objectAtIndex:0]; // first one
	
		cell.textLabel.text = [item placeholder] ? @" ": [NSString stringWithFormat:@"%@", [item label]];
		[self textOrEdit:(UITableViewCellFixed *) cell :item :CGRectMake(110,10, 180, 30)];

	} @catch (NSException * e) {
		
	}
	
	// if the field is editable, show the value in a text field, otherwise 
	// fall back to the detail style
	
	// TODO make a single column wider, currently each is the same width reguardless
	@try {
		
		ZKDescribeLayoutItem *item2 = [[dlr layoutItems] objectAtIndex:1];
		
		[(UITableViewCellFixed *)cell textLabel2].text = [NSString stringWithFormat:@"%@", [item2 label]];
		
		[(UITableViewCellFixed *)cell detailTextLabel2].frame = CGRectMake(590,10, 18, 0);
		
		[self textOrEdit:(UITableViewCellFixed *) cell :item2 :CGRectMake(455,10, 180, 30) ];
		
		[(UITableViewCellFixed *)cell setHasTwoCols:YES];
	}	
	@catch (NSException * e) {
		// if layoutItems is a single column we end up here, it's ok
	}
		
	return cell;
}

#pragma mark -
#pragma mark Manage the edit record

- (void)setDetailItem:(id)newDetailItem 
{
    if (detailItem != newDetailItem) {
        [detailItem release];
        detailItem = [newDetailItem retain];
		[super.tableView reloadData];
    }
}

- (ZKSObject *)saveDetailItem
{
	//NSLog(@"saveDetailItem %@",[detailItem description]);
	// save the object?
	SplitForceAppDelegate *app = (SplitForceAppDelegate *)[[UIApplication sharedApplication] delegate];
	ZKSforceClient *client = app.rootViewController.client;
	@try {
		
		// copy the detailItem into a fresh object that we can perform an update on
		// required: remove non updating fields, set type, set Id, remove related lists
		ZKSObject *upd = [ZKSObject withType:@"account"];
		[upd setFieldValue:[detailItem getId] field:@"Id"]; // need to set as a field (not setId) 
		
		NSEnumerator *e = [[detailItem fields] keyEnumerator];
		NSString *fieldName;
		while(fieldName = [e nextObject]) {
			// check the type of the field before adding
			ZKDescribeField *field = [describe fieldWithName:fieldName];
			if ( [field updateable] ) {
				[upd setFieldValue: [[detailItem fields] valueForKey:fieldName] field:fieldName];
			}
		}
		
		NSArray *objects = [[NSArray alloc] initWithObjects:(ZKSObject *)upd, nil];
		
		[client update: objects];
		
		[upd release];
		
	}
	@catch (NSException * e) {
		NSLog(@" %@ %@",e.name,e.reason );
	}
	return detailItem;
}

#pragma mark - 
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
	NSLog(@"did selectrow at index");
}

#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}

- (void)dealloc {
    [super dealloc];
	[detailLayouSections dealloc];
}
@end
